package com.baomidou.springboot.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.api.ApiResult;
import com.baomidou.springboot.ErrorCode;
import com.baomidou.springboot.entity.Cart;
import com.baomidou.springboot.entity.CartItem;
import com.baomidou.springboot.entity.Product;
import com.baomidou.springboot.entity.TbUser;
import com.baomidou.springboot.entity.vo.CartItemVO;
import com.baomidou.springboot.mapper.CartItemMapper;
import com.baomidou.springboot.mapper.CartMapper;
import com.baomidou.springboot.mapper.ProductMapper;
import com.baomidou.springboot.mapper.TbUserMapper;
import com.baomidou.springboot.service.CartService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;

@RestController
@RequestMapping("/carts")
public class CartController {

    @Autowired
    private CartService cartService;

    @Autowired
    private CartMapper cartMapper;

    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private CartItemMapper cartItemMapper;

    @Autowired
    private TbUserMapper tbUserMapper;


    // 根据用户初始化购物车,获取购物车列表
    @GetMapping("/cart/{userId}")
    public ApiResult getCartList(@PathVariable Long userId) {
        List<Cart> carts = cartMapper.selectList(new QueryWrapper<Cart>().lambda().eq(Cart::getUserId, userId));
        if (carts.size() == 0) {
            long floor = Math.round(Math.random() * 100);
            Long id = new Date().getTime()*100 + floor;
            final Cart cart = new Cart().setUserId(userId).setId(id).setCreateAt(LocalDateTime.now()).setUpdateAt(LocalDateTime.now());

            if (cartMapper.insert(cart) ==0) {
                return ApiResult.failed("创建购物车失败");
            } else {
                ApiResult cartItems = this.getCartItems(cart.getId());
                cartItems.setMsg(String.valueOf(cart.getId()));
                return cartItems;
            }


        } else {
            Cart cart = carts.get(0);
            ApiResult cartItems = this.getCartItems(cart.getId());
            cartItems.setMsg(String.valueOf(cart.getId()));
            return cartItems;
        }
    }

    // 根据购物车id 获取购物车商品列表
    @GetMapping("/{cartId}/items")
    public ApiResult getCartItems(@PathVariable Long cartId) {
        List<CartItem> tmp = cartService.getCartItemsByCartId(cartId);
        List<CartItemVO> list=new ArrayList<>();
        tmp.stream().forEach(v->{
            CartItemVO cartItemVO = new CartItemVO();
            BeanUtils.copyProperties(v, cartItemVO);
            Long productId = v.getProductId();
            Product product = productMapper.selectOne(new QueryWrapper<Product>()
                    .lambda()
                    .eq(Product::getId, productId));
            BeanUtils.copyProperties(product,cartItemVO);
            cartItemVO.setId(v.getId());
            cartItemVO.setProductId(String.valueOf(product.getId()));
            list.add(cartItemVO);
        });
        return ApiResult.restResult(list,ErrorCode.SUCCESS);
    }

    // 添加购物车商品
    @PostMapping("/{userId}/{productId}/items")
    @Transactional(rollbackFor = Exception.class)
    public ApiResult addCartItem(@PathVariable Long userId, @PathVariable Long productId) {

        // 初始化购物车,如果这个用户还没有购物车就初始化完他的购物车
        this.getCartList(userId);

        //为这个购物车添加对应的商品序列
        Product product = productMapper.selectOne(new QueryWrapper<Product>().lambda().eq(Product::getId, productId));
        Cart cart = cartMapper.selectOne(new QueryWrapper<Cart>().lambda().eq(Cart::getUserId, userId));
        // 观察这个商品是否存入表里过没;如果存入表里过就修改数量和价格; 如果没有存在表里过就新加一条数据

        List<CartItem> cartItems = cartItemMapper.selectList(new QueryWrapper<CartItem>().lambda()
                .eq(CartItem::getCartId, cart.getId())
                .eq(CartItem::getProductId, product.getId()));
        if (cartItems.size() != 0 ) {
            // 已有数据 跟新即可
            CartItem cartItem = cartItems.get(0);
            cartItem.setQuantity(cartItem.getQuantity()+1);
            cartItem.setPrice( cartItem.getPrice().add(cartItem.getPrice())  );
            cartItem.setUpdateAt(LocalDateTime.now());
            int i = cartItemMapper.updateById(cartItem);
            if (i != 0) {
                return ApiResult.restResult("添加成功",ErrorCode.SUCCESS);
            } else {
                return ApiResult.restResult("添加失败",ErrorCode.TEST);
            }
        } else {
            // 新加数据
            int insert = cartItemMapper.insert(new CartItem()
                    .setCartId(cart.getId())
                    .setPrice(new BigDecimal(product.getProductPrice()))
                    .setQuantity(1)
                    .setProductId(product.getId())
                    .setCreateAt(LocalDateTime.now())
                    .setUpdateAt(LocalDateTime.now())
            );
            if (insert != 0) {
                return ApiResult.restResult("添加成功",ErrorCode.SUCCESS);
            } else {
                return ApiResult.restResult("添加失败",ErrorCode.TEST);
            }
        }
    }

    // 更新购物车商品
    @PutMapping("/{cartId}/items/{itemId}")
    public ApiResult updateCartItem(@PathVariable Long cartId, @PathVariable Long itemId, @RequestBody CartItem cartItem) {
        // cartId, itemId
        cartItem.setCartId(cartId);
        cartItem.setId(itemId);
        if (cartService.updateCartItem( cartItem )) {
            return ApiResult.failed("添加失败");
        }

        ApiResult<CartItem> ok = ApiResult.ok(cartItem);
        ok.setMsg("添加成功");
        return ok;
    }

    // 删除购物车商品
    @DeleteMapping("/{cartId}/items/{itemId}")
    @Transactional(rollbackFor = Exception.class)
    public ApiResult deleteCartItem(@PathVariable Long cartId, @PathVariable Long itemId) {
        if (!cartService.deleteCartItemById(itemId)) {
            throw new RuntimeException("没有此itemID");
        }
        return ApiResult.ok("删除成功");
    }

    //结算购物车金额
    @PutMapping("/money/{userId}")
    @Transactional(rollbackFor = Exception.class)
    public ApiResult getMoney(@PathVariable Long userId, @RequestBody List<String> list){

        TbUser tbUser = tbUserMapper.selectOne(new QueryWrapper<TbUser>().lambda().eq(TbUser::getId, userId));
        Cart cart = cartMapper.selectOne(new QueryWrapper<Cart>().lambda().eq(Cart::getUserId, userId));
        AtomicReference<BigDecimal> money = new AtomicReference<>(new BigDecimal(0));

//        cartService.deleteCartItemById()

        list.forEach(v->{
            CartItem item = cartItemMapper.selectOne(new QueryWrapper<CartItem>()
                .lambda().eq(CartItem::getCartId, cart.getId())
                .eq(CartItem::getId,Long.valueOf(v))
            );
            if (Objects.isNull(item)) {
                throw  new RuntimeException("1000错误");
            }
            BigDecimal multiply = item.getPrice().multiply(new BigDecimal(item.getQuantity()));
            money.set(money.get().add(multiply));
        });

        BigDecimal bigDecimal = new BigDecimal(tbUser.getMoney());
        //如果用户钱够,就扣减,不够就说不够
        if (bigDecimal.compareTo(money.get()) > 0) {
            BigDecimal subtract = bigDecimal.subtract(money.get());
            tbUser.setMoney(subtract.toString());
            if (tbUserMapper.updateById(tbUser)==0) {
                throw new RuntimeException("修改用户金额失败");
            }

            //扣减金额成功, 删除购物车商品
            list.forEach(v->{
                if(!cartService.deleteCartItemById(Long.valueOf(v)))throw  new RuntimeException("删除购物车商品库存失败");
            });

            return ApiResult.restResult("扣减成功",ErrorCode.SUCCESS);
        }else {
            return ApiResult.restResult("扣减失败",ErrorCode.TEST);
        }
    }
}
